package com.swhysc.information.common.dao.impl;//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import com.swhysc.information.common.dao.IBaseDao;
import com.swhysc.information.common.model.GridView;
import com.swhysc.information.common.model.PageAble;
import com.swhysc.information.dao.transformer.AliasToMapTransformer;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.query.NativeQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Repository
@Transactional(
        propagation = Propagation.REQUIRED,
        rollbackFor = {Exception.class, HibernateException.class}
)
public class BaseDaoImpl<T, ID extends Serializable> implements IBaseDao<T, ID> {
    public static final Logger LOG = LoggerFactory.getLogger(BaseDaoImpl.class);
    @PersistenceContext
    private EntityManager entityManager;



    public GridView findByNativeSQLToGridMap(String sql, Object[] params, PageAble pageAble) {
        NativeQuery query = (new BaseDaoImpl.JpaNativeSql(sql, params)).getQuery();
        query.setResultTransformer(new AliasToMapTransformer());
        query.setFirstResult(pageAble.getOffset());
        query.setMaxResults(pageAble.getPageSize());
        Long totle = this.countByNative(sql, params);
        List list = query.list();
        GridView gv = new GridView(pageAble.getPageSize(), totle.intValue(), list);
        return gv;
    }

    public long countByNative(String sql) {
        String countSql = "select count(1) from ( " + sql + " ) t";
        Query query = (new BaseDaoImpl.JpaNativeSql(countSql)).getQuery();
        long m = Long.parseLong(String.valueOf(query.uniqueResult()));
        return m;
    }

    public long countByNative(String sql, Object[] params) {
        String countSql = "select count(1) from ( " + sql + " ) t";
        Query query = (new BaseDaoImpl.JpaNativeSql(countSql, params)).getQuery();
        long m = Long.parseLong(String.valueOf(query.uniqueResult()));
        return m;
    }

    @Transactional
    public Session getSession() {
        Session session = (Session)this.entityManager.getDelegate();
        return session;
    }

    class JpaNativeSql extends BaseDaoImpl<T, ID>.JpaSql {
        public JpaNativeSql(String hql) {
            super();
            this.query = BaseDaoImpl.this.getSession().createNativeQuery(hql);
        }

        public JpaNativeSql(String hql, Object[] param) {
            super();
            String sql = this.transfer(hql, param);
            if (false) {
                BaseDaoImpl.LOG.info("sql: " + sql);
                BaseDaoImpl.LOG.info("params: " + this.params);
            }

            this.query = BaseDaoImpl.this.getSession().createNativeQuery(sql);
            this.setParameters(this.query, this.params);
        }

        public JpaNativeSql(String hql, Map<String, Object> param) {
            super();
            this.params = param;
            if (false) {
                BaseDaoImpl.LOG.info("sql: " + hql);
                BaseDaoImpl.LOG.info("params: " + this.params);
            }

            this.query = BaseDaoImpl.this.getSession().createNativeQuery(hql);
            this.setParameters(this.query, this.params);
        }

        public NativeQuery getQuery() {
            return (NativeQuery)this.query;
        }
    }

    class JpaSql {
        protected Query query;
        protected Map<String, Object> params;
        private static final String KEY = "p";

        public Query getQuery() {
            return this.query;
        }

        public Map<String, Object> getParams() {
            return this.params;
        }

        public JpaSql() {
        }

        public JpaSql(String hql) {
            if (false) {
                BaseDaoImpl.LOG.info("sql: " + hql);
            }

            this.query = BaseDaoImpl.this.getSession().createQuery(hql);
        }

        public JpaSql(String hql, Map<String, Object> params) {
            this.params = params;
            if (false) {
                BaseDaoImpl.LOG.info("sql: " + hql);
                BaseDaoImpl.LOG.info("params: " + params);
            }

            this.query = BaseDaoImpl.this.getSession().createQuery(hql);
            this.setParameters(this.query, params);
        }

        public JpaSql(Query query, Map<String, Object> params) {
            this.query = query;
            this.params = params;
            this.setParameters(query, params);
        }

        public JpaSql(String hql, Object[] param) {
            String sql = this.transfer(hql, param);
            if (false) {
                BaseDaoImpl.LOG.info("sql: " + sql);
                BaseDaoImpl.LOG.info("params: " + this.params);
            }

            this.query = BaseDaoImpl.this.getSession().createQuery(sql);
            this.setParameters(this.query, this.params);
        }

        protected String transfer(String hql, Object[] param) {
            StringBuilder sql = new StringBuilder(hql);
            if (param == null) {
                return hql;
            } else {
                this.params = new HashMap(param.length);

                int from = 0;

                int index;
                for(int p = 0; (index = sql.indexOf("?", from)) > -1; ++p) {
                    String key = "p" + p;
                    sql.replace(index, index + 1, ":" + key);
                    this.params.put(key, param[p]);
                    from = index;
                }

                return sql.toString();
            }
        }

        protected void setParameters(Query query, Map<String, Object> parameter) {
            if (parameter != null) {
                Iterator keys = parameter.keySet().iterator();

                while(keys.hasNext()) {
                    String key = keys.next().toString();
                    if (!key.equals("callback") && !key.equals("page") && !key.equals("rows")) {
                        if (parameter.get(key) instanceof Collection) {
                            query.setParameterList(key, (Collection)parameter.get(key));
                        } else if (parameter.get(key) instanceof Object[]) {
                            query.setParameterList(key, (Object[])((Object[])parameter.get(key)));
                        } else {
                            query.setParameter(key, parameter.get(key));
                        }
                    }
                }
            }

        }
    }

}
